package furn.controller;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import furn.bean.Furn;
import furn.bean.Msg;
import furn.service.FurnService;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@SuppressWarnings("all")
@Controller
public class FurnController {

    //注入一个FurnService属性【接口对象】。可直接调用该对象的方法。
    //即 web层  调用  service层
    @Resource
    private FurnService furnService;

    /**
     * 1、响应客户端发送的添加请求
     * 2、@RequestBody：表示将客户端提交的JSON数据封装到Furn对象中
     * 3、@ResponseBody：表示将返回数据封装成JSON数据响应给客户端【底层是按照http协议进行协商】
     * 4、@Validated ：表示对Furn对象进行校验
     * 5、errors: 表示校验结果.底层校验过后会把错误信息封装到errors对象中
     *
     * @param furn
     * @return
     */
    @PostMapping("/save")
    @ResponseBody
    public Msg save(@Validated @RequestBody Furn furn, Errors errors) {
        //编写一个map集合,保存所有错误信息
        Map<String, Object> map = new HashMap<>();
        //获取所有字段的校验结果
        List<FieldError> fieldErrors = errors.getFieldErrors();
        for (FieldError fieldError : fieldErrors) {
            //将各字段的名字和错误信息封装到map集合中
            map.put(fieldError.getField(), fieldError.getDefaultMessage());
        }
        if (map.isEmpty()) {   //如果map集合为空，则说明校验通过，可以添加家居信息
            furnService.save(furn);
            //返回成功信息
            Msg success = Msg.success();
            return success;
        } else {
            //校验失败，将错误信息封装到msg实例对象中并返回
            return Msg.fail().add("errorMsg", map);
        }
    }

    /**
     * 1、响应客户端发送的查询请求
     * 2、@ResponseBody：表示将返回数据封装成JSON数据响应给客户端【底层是按照http协议进行协商】
     * 3、该方法除了返回成功信息外，还需要将查询到的家居信息封装到msg实例对象中
     *
     * @return
     */
    @RequestMapping("/furns")
    @ResponseBody
    public Msg listFurns() {
        List<Furn> furnList = furnService.findAll();
        //调用Msg类的静态方法success()得到一个msg实例对象
        Msg successMsg = Msg.success();
        //msg实例对象调用add方法，将返回的家居信息封装到msg实例对象中
        successMsg.add("furnList", furnList);
        return successMsg;
    }

    /**
     * 1、响应客户端发送的修改请求
     *
     * @param furn
     * @return
     */
    @PutMapping("/update")
    @ResponseBody
    public Msg update(@RequestBody Furn furn) {
        furnService.update(furn);
        //修改家居信息成功后，返回成功信息
        return Msg.success();
    }

    /**
     * 1、响应客户端发送的删除请求
     * 2、@PathVariable：表示将客户端发送的id值封装到id变量【路径变量】
     * @param id
     * @return
     */
    @DeleteMapping("/delete/{id}")
    @ResponseBody
    public Msg delete(@PathVariable Integer id) {
        furnService.delete(id);
        return Msg.success();
    }

    /**
     * 1、响应客户端发送的查询请求
     * 2、@PathVariable：表示将客户端发送的id值封装到id变量【路径变量】
     * 3、@ResponseBody：表示将返回数据封装成JSON数据响应给客户端【底层是按照http协议进行协商】
     * 4、该方法除了返回成功信息外，还需要将查询到的家居信息封装到msg实例对象中
     * @param id
     * @return
     */
    @GetMapping("/findById/{id}")
    @ResponseBody
    public Msg findById(@PathVariable Integer id) {
        //调用service层方法，查询家居信息
        Furn furn = furnService.findById(id);
        //调用Msg类的静态方法success()得到一个msg实例对象。该对象目前只有 状态码code属性 和 说明信息msg属性 已赋值
        Msg msg = Msg.success();
        //msg实例对象调用add方法，将家居信息封装到自身的extend属性集合中
        return msg.add("furn", furn);
    }

    /**
     * 1、响应客户端发送的分页查询请求
     * 2、pageNum：表示要显示第几页【@RequestParam(defaultValue = "1") 表示默认值是1】
     * 3、pageSize：表示每页显示多少条数据【@RequestParam(defaultValue = "5") 表示默认值是5】
     *
     * @param pageNum
     * @param pageSize
     * @return
     */
    @ResponseBody
    @RequestMapping("/furnsByPage")
    public Msg listFurnsByPage(@RequestParam(defaultValue = "1") Integer pageNum,
                               @RequestParam(defaultValue = "5") Integer pageSize) {
        //1、设置分页参数
        PageHelper.startPage(pageNum, pageSize);
        //2、调用service层方法，查询家居信息
        //(1)调用findAll完成查询。底层会进行物理分页，而不是逻辑分页
        //(2)底层会根据分页参数来计算limit ?, ?, 并在发出SQL语句时，会带 limit 关键字进行分页查询
        List<Furn> furnList = furnService.findAll();
        //3、将分页查询的结果，封装到PageInfo对象中
        //(1)PageInfo对象中封装了分页查询的结果
        //(2)PageInfo对象中封装了分页的参数【pageNum, pageSize, total, pages, list等】
        PageInfo pageInfo = new PageInfo(furnList, pageSize);
        //4、将pageInfo对象封装到msg实例对象中，并返回
        Msg msg = Msg.success();
        return msg.add("pageInfo", pageInfo);
    }


    /**
     * 1、响应客户端发送的分页查询请求[按照name模糊查询]
     * @param pageNum
     * @param pageSize
     * @return
     */
    @ResponseBody
    @RequestMapping("/furnsByNamePage")
    public Msg listFurnsByNamePage(@RequestParam(defaultValue = "1") Integer pageNum,
                                   @RequestParam(defaultValue = "5") Integer pageSize,
                                   @RequestParam(defaultValue = "") String search) {
        //1、设置分页参数
        PageHelper.startPage(pageNum, pageSize);
        //2、调用service层方法，查询家居信息
        //(1)调用findByName完成查询。底层会进行物理分页，而不是逻辑分页
        //(2)底层会根据分页参数来计算limit ?, ?, 并在发出SQL语句时，会带 limit 关键字进行分页查询
        List<Furn> furnList = furnService.findByName(search);
        //3、将分页查询的结果，封装到PageInfo对象中
        //(1)PageInfo对象中封装了分页查询的结果
        //(2)PageInfo对象中封装了分页的参数【pageNum, pageSize, total, pages, list等】
        PageInfo pageInfo = new PageInfo(furnList, pageSize);
        //4、将pageInfo对象封装到msg实例对象中，并返回
        Msg msg = Msg.success();
        return msg.add("pageInfo", pageInfo);
    }

}
